﻿using DataService;
using DataService.Group;
using DataService.Interfaces;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Sockets;

namespace CoreTest;

[Description("客户端驱动")]
public class ClientReader : IDriver//客户端存在对TLV数据的字节序转换问题，需测试
{
    public ClientReader(IDataServer server, short id, string name)
    {
        _id = id;
        _server = server;
        _name = name;
    }

    short _id;
    public short ID => _id;

    private int _timeout = 0;
    public int TimeOut
    {
        get => _timeout;
        set => _timeout = value;
    }

    string _name;
    public string Name => _name;

    string _ip;
    public string ServerName
    {
        get => _ip;
        set => _ip = value;
    }

    internal Socket tcpSend;
    internal Socket tcpRecive;

    public bool IsClosed =>
            tcpSend == null || tcpRecive == null || !tcpSend.Connected || !tcpRecive.Connected;

    List<IGroup> _grps = new List<IGroup>(1);
    public IEnumerable<IGroup> Groups => _grps;

    IDataServer _server;
    public IDataServer Parent => _server;


    public bool Connect()
    {
        int port = 6543;
        lock (this)
        {
            try
            {
                if (tcpRecive != null)
                {
                    tcpRecive.Dispose();
                }
                if (tcpSend != null)
                {
                    tcpSend.Dispose();
                }
                tcpRecive = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                tcpRecive.Connect(_ip, port);
                tcpRecive.SendTimeout = _timeout;
                tcpRecive.ReceiveTimeout = -1;

                tcpSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                tcpSend.Connect(_ip, port);
                tcpSend.SendTimeout = _timeout;
                tcpSend.ReceiveTimeout = _timeout;
                return true;
            }
            catch (SocketException error)
            {
                if (OnError != null)
                    OnError(this, new IOErrorEventArgs(error.Message));
                return false;
            }
        }
    }

    public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false)
    {
        ClientGroup grp = new ClientGroup(id, name, updateRate, active, this);
        _grps.Add(grp);
        return grp;
    }

    public bool RemoveGroup(IGroup grp)
    {
        grp.IsActive = false;
        return _grps.Remove(grp);
    }

    public event IOErrorEventHandler OnError;

    public void Dispose()
    {
        foreach (IGroup grp in _grps)
        {
            grp.Dispose();
        }
        _grps.Clear();
        try
        {
            if (tcpRecive != null)
            {
                if (tcpRecive.Connected)
                    tcpRecive.Shutdown(SocketShutdown.Both);
                tcpRecive.Dispose();
            }
            if (tcpSend != null)
            {
                if (tcpSend.Connected)
                    tcpSend.Shutdown(SocketShutdown.Both);
                tcpSend.Dispose();
            }
        }
        catch (SocketException err)
        {
            if (OnError != null)
                OnError(this, new IOErrorEventArgs(err.Message));
        }
    }
}
